package edu.northwestern.cbits.purple_robot_manager.activities;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.UUID;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.view.ContextThemeWrapper;
import edu.emory.mathcs.backport.java.util.Collections;
import edu.northwestern.cbits.purple_robot_manager.R;
import edu.northwestern.cbits.purple_robot_manager.logging.LogManager;
import edu.northwestern.cbits.purple_robot_manager.scripting.BaseScriptEngine;
public class DialogActivity extends Activity
{
public static final String DIALOG_TAG = "dialog_tag";
public static final String DIALOG_PRIORITY = "dialog_priority";
public static final String DIALOG_ADDED = "dialog_added";
public static String DIALOG_MESSAGE = "dialog_message";
public static String DIALOG_TITLE = "dialog_title";
public static String DIALOG_CONFIRM_BUTTON = "dialog_confirm";
public static String DIALOG_CANCEL_BUTTON = "dialog_cancel";
public static String DIALOG_CONFIRM_SCRIPT = "dialog_confirm_script";
public static String DIALOG_CANCEL_SCRIPT = "dialog_cancel_script";
private static ArrayList<HashMap<String, Object>> _pendingDialogs = new ArrayList<>();
private static boolean _visible = false;
private static AlertDialog _currentDialog = null;
private static DialogActivity _currentActivity = null;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.layout_dialog_background_activity);
DialogActivity._visible = true;
}
protected void onDestroy()
{
DialogActivity._visible = false;
super.onDestroy();
}
public static void showNativeDialog(final Context context, final String title, final String message,
final String confirmTitle, final String cancelTitle, final String confirmScript, final String cancelScript,
final String tag, final long priority)
{
try
{
Thread.sleep(250);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
if (title == null)
{
DialogActivity.showNativeDialog(context, "", message, confirmTitle, cancelTitle, confirmScript,
cancelScript, tag, priority);
return;
}
if (message == null)
{
DialogActivity.showNativeDialog(context, title, "", confirmTitle, cancelTitle, confirmScript, cancelScript,
tag, priority);
return;
}
if (confirmTitle == null)
{
DialogActivity.showNativeDialog(context, title, message, "", cancelTitle, confirmScript, cancelScript, tag,
priority);
return;
}
if (confirmScript == null)
{
DialogActivity.showNativeDialog(context, title, message, confirmTitle, cancelTitle, "", cancelScript, tag,
priority);
return;
}
if (cancelTitle == null)
{
DialogActivity.showNativeDialog(context, title, message, confirmTitle, "", confirmScript, cancelScript,
tag, priority);
return;
}
if (cancelScript == null)
{
DialogActivity.showNativeDialog(context, title, message, confirmTitle, cancelTitle, confirmScript, "", tag,
priority);
return;
}
if (tag == null || "".equals(tag))
{
DialogActivity.showNativeDialog(context, title, message, confirmTitle, cancelTitle, confirmScript,
cancelScript, UUID.randomUUID().toString(), priority);
return;
}
if (!DialogActivity._visible)
{
DialogActivity._visible = true;
Intent intent = new Intent(context, DialogActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(DialogActivity.DIALOG_TITLE, title);
intent.putExtra(DialogActivity.DIALOG_MESSAGE, message);
intent.putExtra(DialogActivity.DIALOG_CONFIRM_BUTTON, confirmTitle);
intent.putExtra(DialogActivity.DIALOG_CONFIRM_SCRIPT, confirmScript);
intent.putExtra(DialogActivity.DIALOG_CANCEL_BUTTON, cancelTitle);
intent.putExtra(DialogActivity.DIALOG_CANCEL_SCRIPT, cancelScript);
intent.putExtra(DialogActivity.DIALOG_TAG, tag);
intent.putExtra(DialogActivity.DIALOG_ADDED, System.currentTimeMillis());
intent.putExtra(DialogActivity.DIALOG_PRIORITY, priority);
context.startActivity(intent);
}
else
{
final Handler handler = new Handler(Looper.getMainLooper());
Runnable r = new Runnable()
{
public void run()
{
if (DialogActivity._currentActivity == null)
{
handler.postDelayed(this, 100);
return;
}
Intent intent = DialogActivity._currentActivity.getIntent();
if (intent.getLongExtra(DialogActivity.DIALOG_PRIORITY, 0) < priority)
{
HashMap<String, Object> dialog = new HashMap<>();
dialog.put(DialogActivity.DIALOG_TITLE, intent.getStringExtra(DialogActivity.DIALOG_TITLE));
dialog.put(DialogActivity.DIALOG_MESSAGE, intent.getStringExtra(DialogActivity.DIALOG_MESSAGE));
dialog.put(DialogActivity.DIALOG_CONFIRM_BUTTON,
intent.getStringExtra(DialogActivity.DIALOG_CONFIRM_BUTTON));
dialog.put(DialogActivity.DIALOG_CONFIRM_SCRIPT,
intent.getStringExtra(DialogActivity.DIALOG_CONFIRM_SCRIPT));
dialog.put(DialogActivity.DIALOG_CANCEL_BUTTON,
intent.getStringExtra(DialogActivity.DIALOG_CANCEL_BUTTON));
dialog.put(DialogActivity.DIALOG_CANCEL_SCRIPT,
intent.getStringExtra(DialogActivity.DIALOG_CANCEL_SCRIPT));
dialog.put(DialogActivity.DIALOG_TAG, intent.getStringExtra(DialogActivity.DIALOG_TAG));
dialog.put(DialogActivity.DIALOG_ADDED,
intent.getLongExtra(DialogActivity.DIALOG_ADDED, System.currentTimeMillis()));
dialog.put(DialogActivity.DIALOG_PRIORITY,
intent.getLongExtra(DialogActivity.DIALOG_PRIORITY, 0));
DialogActivity._pendingDialogs.add(dialog);
// Tag changed to current one so the dialog gets
// refreshed below...
intent.putExtra(DialogActivity.DIALOG_TAG, tag);
}
HashMap<String, Object> dialog = new HashMap<>();
dialog.put(DialogActivity.DIALOG_TITLE, title);
dialog.put(DialogActivity.DIALOG_MESSAGE, message);
dialog.put(DialogActivity.DIALOG_CONFIRM_BUTTON, confirmTitle);
dialog.put(DialogActivity.DIALOG_CONFIRM_SCRIPT, confirmScript);
dialog.put(DialogActivity.DIALOG_CANCEL_BUTTON, cancelTitle);
dialog.put(DialogActivity.DIALOG_CANCEL_SCRIPT, cancelScript);
dialog.put(DialogActivity.DIALOG_TAG, tag);
dialog.put(DialogActivity.DIALOG_ADDED, System.currentTimeMillis());
dialog.put(DialogActivity.DIALOG_PRIORITY, priority);
DialogActivity.clearNativeDialogs(context, tag, dialog);
}
};
handler.postDelayed(r, 100);
}
}
protected void onResume()
{
super.onResume();
this.showNativeDialog();
}
@SuppressLint("NewApi")
private void showNativeDialog()
{
Intent intent = this.getIntent();
String title = intent.getStringExtra(DialogActivity.DIALOG_TITLE);
String message = intent.getStringExtra(DialogActivity.DIALOG_MESSAGE);
String confirmTitle = intent.getStringExtra(DialogActivity.DIALOG_CONFIRM_BUTTON);
final String confirmScript = intent.getStringExtra(DialogActivity.DIALOG_CONFIRM_SCRIPT);
final DialogActivity me = this;
ContextThemeWrapper wrapper = new ContextThemeWrapper(this, R.style.Theme_AppCompat);
AlertDialog.Builder builder = new AlertDialog.Builder(wrapper);
builder = builder.setTitle(title);
builder = builder.setMessage(message);
builder = builder.setCancelable(false);
if (confirmTitle.trim().length() > 0)
{
builder = builder.setPositiveButton(confirmTitle, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
if (confirmScript != null && confirmScript.trim().length() > 0)
{
Runnable r = new Runnable()
{
public void run()
{
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
BaseScriptEngine.runScript(me, confirmScript);
}
};
Thread t = new Thread(r);
t.start();
}
}
});
}
String cancelTitle = intent.getStringExtra(DialogActivity.DIALOG_CANCEL_BUTTON);
final String cancelScript = intent.getStringExtra(DialogActivity.DIALOG_CANCEL_SCRIPT);
if (cancelTitle.trim().length() > 0)
{
builder = builder.setNegativeButton(cancelTitle, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
if (cancelScript != null && cancelScript.trim().length() > 0)
{
Runnable r = new Runnable()
{
public void run()
{
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
BaseScriptEngine.runScript(me, cancelScript);
}
};
Thread t = new Thread(r);
t.start();
}
}
});
}
DialogActivity._currentDialog = builder.create();
DialogActivity._currentDialog.setOnDismissListener(new OnDismissListener()
{
public void onDismiss(DialogInterface dialogInterface)
{
DialogActivity._currentDialog = null;
DialogActivity._currentActivity = null;
DialogActivity._visible = false;
if (DialogActivity._pendingDialogs.size() > 0)
{
DialogActivity.sortPending();
HashMap<String, Object> dialog = DialogActivity._pendingDialogs.remove(0);
Intent intent = new Intent();
intent.putExtra(DialogActivity.DIALOG_TITLE, dialog.get(DialogActivity.DIALOG_TITLE).toString());
intent.putExtra(DialogActivity.DIALOG_MESSAGE, dialog.get(DialogActivity.DIALOG_MESSAGE).toString());
intent.putExtra(DialogActivity.DIALOG_CONFIRM_BUTTON,
dialog.get(DialogActivity.DIALOG_CONFIRM_BUTTON).toString());
intent.putExtra(DialogActivity.DIALOG_CONFIRM_SCRIPT,
dialog.get(DialogActivity.DIALOG_CONFIRM_SCRIPT).toString());
intent.putExtra(DialogActivity.DIALOG_CANCEL_BUTTON, dialog
.get(DialogActivity.DIALOG_CANCEL_BUTTON).toString());
intent.putExtra(DialogActivity.DIALOG_CANCEL_SCRIPT, dialog
.get(DialogActivity.DIALOG_CANCEL_SCRIPT).toString());
intent.putExtra(DialogActivity.DIALOG_TAG, dialog.get(DialogActivity.DIALOG_TAG).toString());
intent.putExtra(DialogActivity.DIALOG_PRIORITY, (Long) dialog.get(DialogActivity.DIALOG_PRIORITY));
me.setIntent(intent);
me.showNativeDialog();
}
else
me.finish();
}
});
DialogActivity._currentActivity = this;
DialogActivity._currentDialog.show();
}
private static void sortPending()
{
Collections.sort(DialogActivity._pendingDialogs, new Comparator<HashMap<String, Object>>()
{
public int compare(HashMap<String, Object> one, HashMap<String, Object> two)
{
String priorityOne = one.get(DialogActivity.DIALOG_PRIORITY).toString();
String priorityTwo = two.get(DialogActivity.DIALOG_PRIORITY).toString();
long pOne = Long.parseLong(priorityOne);
long pTwo = Long.parseLong(priorityTwo);
if (pOne < pTwo)
return 1;
else if (pOne > pTwo)
return -1;
Long addedOne = (Long) one.get(DialogActivity.DIALOG_ADDED);
Long addedTwo = (Long) two.get(DialogActivity.DIALOG_ADDED);
return addedOne.compareTo(addedTwo);
}
});
}
public static void clearNativeDialogs(final Context context)
{
DialogActivity._pendingDialogs.clear();
if (DialogActivity._currentDialog != null && DialogActivity._currentActivity != null)
{
DialogActivity._currentActivity.runOnUiThread(new Runnable()
{
public void run()
{
try
{
if (DialogActivity._currentDialog.isShowing())
DialogActivity._currentDialog.dismiss();
}
catch (IllegalArgumentException e)
{
LogManager.getInstance(context).logException(e);
}
}
});
}
}
public static void clearNativeDialogs(final Context context, String tag, HashMap<String, Object> replacement)
{
ArrayList<HashMap<String, Object>> toRemove = new ArrayList<>();
for (HashMap<String, Object> dialog : DialogActivity._pendingDialogs)
{
if (tag.equals(dialog.get(DialogActivity.DIALOG_TAG)))
{
toRemove.add(dialog);
}
}
DialogActivity._pendingDialogs.removeAll(toRemove);
if (replacement != null)
DialogActivity._pendingDialogs.add(replacement);
DialogActivity.sortPending();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
int stackCount = Integer.parseInt(prefs.getString("config_dialog_count", "4"));
while (DialogActivity._pendingDialogs.size() >= stackCount && stackCount > 0)
{
DialogActivity._pendingDialogs.remove(DialogActivity._pendingDialogs.size() - 1);
}
if (DialogActivity._currentDialog != null && DialogActivity._currentActivity != null)
{
Intent intent = DialogActivity._currentActivity.getIntent();
if (tag.equals(intent.getStringExtra(DialogActivity.DIALOG_TAG)))
{
DialogActivity._currentActivity.runOnUiThread(new Runnable()
{
public void run()
{
try
{
if (DialogActivity._currentDialog.isShowing())
{
DialogActivity._currentDialog.dismiss();
}
}
catch (IllegalArgumentException e)
{
LogManager.getInstance(context).logException(e);
}
}
});
}
}
}
}